using System.Collections.Concurrent;
using System.Net.Sockets;
using System.Runtime.InteropServices;

namespace muduoDotNet
{
    /// <summary>
    /// 异步IO事件类型
    /// </summary>
    [Flags]
    public enum AsyncEventType
    {
        None = 0,
        Read = 1,
        Write = 2,
        Error = 4,
        Close = 8
    }

    /// <summary>
    /// 异步IO完成事件参数
    /// </summary>
    public class AsyncEventArgs
    {
        public Channel? Channel { get; set; }
        public AsyncEventType EventType { get; set; }
        public int BytesTransferred { get; set; }
        public SocketError SocketError { get; set; }
        public Exception? Exception { get; set; }
    }

    /// <summary>
    /// 跨平台异步IO轮询器基类
    /// </summary>
    public abstract class AsyncPoller : Poller
    {
        protected readonly ConcurrentQueue<AsyncEventArgs> _completedEvents;
        protected readonly object _eventLock;
        protected volatile bool _isPolling;

        protected AsyncPoller(EventLoop loop) : base(loop)
        {
            _completedEvents = new ConcurrentQueue<AsyncEventArgs>();
            _eventLock = new object();
            _isPolling = false;
        }

        /// <summary>
        /// 启动异步操作
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="eventType">事件类型</param>
        public abstract void StartAsyncOperation(Channel channel, AsyncEventType eventType);

        /// <summary>
        /// 取消异步操作
        /// </summary>
        /// <param name="channel">通道</param>
        public abstract void CancelAsyncOperation(Channel channel);

        /// <summary>
        /// 获取完成的事件
        /// </summary>
        /// <returns>完成的事件列表</returns>
        protected List<AsyncEventArgs> GetCompletedEvents()
        {
            var events = new List<AsyncEventArgs>();
            while (_completedEvents.TryDequeue(out var eventArgs))
            {
                events.Add(eventArgs);
            }
            return events;
        }

        /// <summary>
        /// 添加完成事件
        /// </summary>
        /// <param name="eventArgs">事件参数</param>
        protected void AddCompletedEvent(AsyncEventArgs eventArgs)
        {
            _completedEvents.Enqueue(eventArgs);
        }

        public override List<Channel> Poll(int timeoutMs)
        {
            var activeChannels = new List<Channel>();

            try
            {
                // 等待异步操作完成
                WaitForAsyncOperations(timeoutMs);

                // 处理完成的事件
                var completedEvents = GetCompletedEvents();
                foreach (var eventArgs in completedEvents)
                {
                    var channel = eventArgs.Channel;
                    if (channel == null) continue;

                    // 设置返回事件
                    channel.Revents = ConvertToEventType(eventArgs.EventType);
                    
                    // 处理错误
                    if (eventArgs.Exception != null || eventArgs.SocketError != SocketError.Success)
                    {
                        channel.Revents |= EventType.ErrorEvent;
                        Logger.Warning($"Async operation error for channel {channel.Fd}: {eventArgs.SocketError}");
                    }

                    if (!activeChannels.Contains(channel))
                    {
                        activeChannels.Add(channel);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Error in AsyncPoller.Poll", ex);
            }

            return activeChannels;
        }

        /// <summary>
        /// 等待异步操作完成
        /// </summary>
        /// <param name="timeoutMs">超时时间</param>
        protected abstract void WaitForAsyncOperations(int timeoutMs);

        /// <summary>
        /// 转换事件类型
        /// </summary>
        private EventType ConvertToEventType(AsyncEventType asyncEventType)
        {
            EventType result = EventType.None;
            
            if (asyncEventType.HasFlag(AsyncEventType.Read))
                result |= EventType.ReadEvent;
            if (asyncEventType.HasFlag(AsyncEventType.Write))
                result |= EventType.WriteEvent;
            if (asyncEventType.HasFlag(AsyncEventType.Error))
                result |= EventType.ErrorEvent;
            if (asyncEventType.HasFlag(AsyncEventType.Close))
                result |= EventType.ErrorEvent;

            return result;
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (disposing)
            {
                _isPolling = false;
                // 清理完成事件队列
                while (_completedEvents.TryDequeue(out _)) { }
            }
        }
    }
}